export default abstract class BasicCanvas {
  ctx: CanvasRenderingContext2D

  constructor(protected canvas: HTMLCanvasElement, protected canvasConfig: CanvasConfig) {
    this.ctx = this.canvas.getContext('2d')!
    this.init()
  }

  abstract draw(): void

  init() {
    this.canvas.width = this.canvasConfig.width
    this.canvas.height = this.canvasConfig.height
  }

  protected drawLine(startPoint: [number, number], endPoint: [number, number], lineWidth = 1, strokeStyle = '#000') {
    this.ctx.beginPath()
    this.ctx.lineWidth = lineWidth
    this.ctx.strokeStyle = strokeStyle
    this.ctx.moveTo(...startPoint)
    this.ctx.lineTo(...endPoint)
    this.ctx.stroke()
    this.ctx.closePath()
  }

  protected drawText(
    txt: string,
    point: [number, number],
    font: string = '12px consolas',
    textAlign: CanvasTextAlign = 'center',
    textBaseline: CanvasTextBaseline = 'middle',
    fillStyle: string = '#000',
  ) {
    this.ctx.save()
    this.ctx.translate(...point)
    this.ctx.scale(1, -1)
    this.ctx.beginPath()
    this.ctx.font = font
    this.ctx.textAlign = textAlign
    this.ctx.textBaseline = textBaseline
    this.ctx.fillStyle = fillStyle
    this.ctx.fillText(txt, 0, 0)
    this.ctx.closePath()
    this.ctx.restore()
  }

  protected drawCircle(
    point: [number, number],
    radius: number,
    isfill: boolean = false,
    strokeStyle: string = '#000',
    fillStyle: string = '#000',
  ) {
    this.ctx.save()
    this.ctx.translate(...point)
    this.ctx.beginPath()
    this.ctx.arc(0, 0, radius, 0, 2 * Math.PI)
    this.ctx.strokeStyle = strokeStyle
    this.ctx.fillStyle = fillStyle
    isfill ? this.ctx.fill() : this.ctx.stroke()
    this.ctx.closePath()
    this.ctx.restore()
  }

  // 绘制多段线
  protected drawPolyline(pos: [x: number, y: number][], color = 'black', lineWidth = 2) {
    this.ctx.beginPath()
    this.ctx.moveTo(...pos[0])
    for (let index = 1; index < pos.length; index++) {
      this.ctx.lineTo(...pos[index])
    }
    this.ctx.strokeStyle = color
    this.ctx.lineWidth = lineWidth
    this.ctx.stroke()
  }
}
